home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1996 September
/
MACPOWER-1996-09.ISO.7z
/
MACPOWER-1996-09.ISO
/
第2特集:プラグイン大集合
/
PIC2 Save
/
p2loadhi.c
< prev
next >
Wrap
Text File
|
1995-01-16
|
8KB
|
476 lines
/*
* PIC2 高速フォーマットの展開 by やなぎさわ
*/
#include "pic2.h"
/* ----- 各種変数(p2構造体の中を直接使わないのは、昔作ったのを直すのがめんどうなのと
微妙に型が違うのでキャストの嵐になっていまうからです ----- */
static uchar *fbufp;
static long n_fbuf;
static ushort bit_buf;
static short n_bit_buf;
static long cache8_pos;
static long len;
static long len2;
static P2 *p2;
static pix *vram_prev;
static pix *vram_now;
static pix *vram_next;
static schar *flag_now;
static schar *flag_next;
static pix (_HUGE_ *cache)[N_CACHE];
static ushort *cache_pos;
static short ynow;
static pix (*read_color)( pix bc);
/* エラー時の脱出用 */
static jmp_buf jmp_env;
/*
* 指定したビットするだけファイルから読み込む
*/
static ulong /* 読んだ値 */
bit_load(
long size /* ビット長 */
)
{
ulong a = 0;
/* 8bitづつバッファリングするので */
bit_buf &= 0xff;
/* 残りのビット数より指定ビット数が大きい場合 */
while ( size > n_bit_buf) {
/* ビットバッファの残りを8ビット超にもってくる */
bit_buf = bit_buf << n_bit_buf;
/* のこりビットを一気に入れるのでその分あける */
a = a << n_bit_buf;
/* のこりは8ビット超にあるので、それを8つ右シフトして、それ自身を入れる */
a = a + ( bit_buf >> 8);
/* 読み込みサイズ更新 */
size -= n_bit_buf;
/* バッファにデータがなければ次のデータをバッファに読み込む */
if ( n_fbuf == 0) {
fbufp = p2->fbuf;
n_fbuf = read_file2( p2, fbufp, N_FBUF);
if ( n_fbuf == 0) {
p2errno = p2->errno = P2E_FEOF;
longjmp( jmp_env, 1);
}
}
/* ビットバッファを更新 */
--n_fbuf;
bit_buf = *fbufp++;
n_bit_buf = 8;
}
/* データにsizeビット入れるので、その分あける */
a = a << size;
/* そのデータを8ビット超にもってきて */
bit_buf = bit_buf << size;
/* それを入れる */
a = a + ( bit_buf >> 8);
n_bit_buf -= size;
return ( a);
}
/*
* 長さデータを読み込む
*/
static long /* 長さ */
read_len( void)
{
long a;
a = 0;
while (bit_load( 1)) {
a++;
}
if ( a == 0) return ( 0);
return ( bit_load( a) + (1 << a) - 1);
}
/*
* 連鎖を展開
*/
static void
expand_chain( long x, pix cc)
{
if ( bit_load(1) != 0) {
if ( bit_load(1) != 0) { /* 下 */
vram_next[ x] = cc;
flag_next[ x] = -1;
} else if ( bit_load(1) != 0) {
if ( bit_load(1) == 0) { /* 左2下 */
vram_next[ x - 2] = cc;
flag_next[ x - 2] = -1;
} else { /* 左1下 */
vram_next[ x - 1] = cc;
flag_next[ x - 1] = -1;
}
} else {
if ( bit_load(1) == 0) { /* 右2下 */
vram_next[ x + 2] = cc;
flag_next[ x + 2] = -1;
} else { /* 左1下 */
vram_next[ x + 1] = cc;
flag_next[ x + 1] = -1;
}
}
}
}
/*
* 24bit色のよみこみ
*/
static pix
read_color24( pix bc)
{
pix cc;
long j,k,m;
k = bc >> 16;
if ( bit_load( 1) == 0) {
cache_pos[k] = m = (cache_pos[k] - 1) & (N_CACHE - 1);
cc = cache[k][m] = bit_load( 24);
} else {
j = bit_load( 6); /* 6= log2(n_cache) */
m = cache_pos[k];
cc = cache[k][(m + j) & (N_CACHE - 1)];
}
return ( cc);
}
/*
* 15bit色のよみこみ
*/
static pix
read_color15( pix bc)
{
pix cc;
long j,k,m;
k = bc >> 8;
if ( bit_load( 1) == 0) {
cache_pos[k] = m = (cache_pos[k] - 1) & (N_CACHE - 1);
cc = cache[k][m] = bit_load( 15) * 2;
} else {
j = bit_load( 6);
m = cache_pos[k];
cc = cache[k][(m + j) & (N_CACHE -1 )];
}
return ( cc);
}
/*
* 8bit色 よみこみ
*/
static uchar
read_color8( void)
{
uchar *cache8 = (uchar *)(cache_pos + 256);
uchar cc;
long i,n;
if ( bit_load( 1) == 0) {
/* はずれ */
for ( i = 16; i > 0; i--) {
cache8[ i] = cache8[ i - 1];
}
cache8[ 0] = cc = bit_load( 8);
} else {
/* あたり */
n = bit_load(4);
cc = cache8[ n];
for ( i = n; i > 0; i--) {
cache8[ i] = cache8[ i - 1];
}
cache8[0] = cc;
}
return ( cc);
}
/*
* 8(16)bit色のよみこみ
*/
static pix
read_color16( pix bc)
{
pix cc;
long i,n,k;
k = bc & 255;
if ( bit_load( 1) == 0) {
/* はずれ */
cc = read_color8();
cc = (cc << 8) + read_color8();
for ( i = 16; i > 0; i--) {
cache[k][i] = cache[k][i - 1];
}
cache[k][0] = cc;
} else {
/* あたり */
n = bit_load( 4);
cc = cache[k][n];
for ( i = n; i > 0; i--) {
cache[k][i] = cache[k][i - 1];
}
cache[k][0] = cc;
}
return ( cc);
}
#if 0
/*
* 8bit色 よみこみ
*/
static uchar
read_color8( void)
{
uchar *cache8 = (uchar *)(cache_pos + 256);
uchar cc;
if ( bit_load( 1) == 0) {
/* はずれ */
cc = bit_load( 8);
cache8_pos = (cache8_pos - 1) & 7;
cache8[ cache8_pos] = cc;
} else {
/* あたり */
cc = cache8[( bit_load(3) + cache8_pos) & 7];
}
return ( cc);
}
/*
* 8(16)bit色のよみこみ
*/
static pix
read_color16( pix bc)
{
pix cc;
long j,k,m;
k = bc & 255;
if ( bit_load( 1) == 0) {
/* はずれ */
cc = read_color8();
cc = (cc << 8) + read_color8();
cache_pos[k] = m = (cache_pos[k] - 1) & 31;
cache[k][m] = cc;
} else {
/* あたり */
j = bit_load( 5);
m = cache_pos[k];
cc = cache[k][(m + j) & 31];
}
return ( cc);
}
#endif
/* 構造体アクセスをケチするため */
static void
para_out( void)
{
fbufp = p2->fbufp;
n_fbuf = p2->n_fbuf;
bit_buf = p2->bit_buf;
n_bit_buf = p2->n_bit_buf;
len = p2->aa;
len2 = p2->dd;
read_color = p2->func;
ynow = p2->ynow;
cache8_pos = p2->data;
vram_prev = p2->vram_prev + 4;
vram_now = p2->vram_now + 4;
vram_next = p2->vram_next + 4;
flag_now = p2->flag_now + 4;
flag_next = p2->flag_next + 4;
cache = (pix (_HUGE_ *)[N_CACHE])p2->cache;
cache_pos = p2->cache_pos;
}
static void
para_in( void)
{
void *p;
p2->fbufp = fbufp;
p2->n_fbuf = n_fbuf;
p2->bit_buf = bit_buf;
p2->n_bit_buf = n_bit_buf;
p2->aa = len;
p2->dd = len2;
p2->func = read_color;
p2->data = cache8_pos;
p = p2->vram_prev;
p2->vram_prev = p2->vram_now;
p2->vram_now = p2->vram_next;
p2->vram_next = p;
p = p2->flag_now;
p2->flag_now = p2->flag_next;
p2->flag_next = p;
p2->ynow = ynow;
}
/*
* 行単位の展開
*/
static long
line_expand( P2 *pp2, pix **line)
{
long ymax;
long x,xw;
pix cc;
if ( setjmp( jmp_env) != 0) return ( -1);
p2 = pp2;
para_out();
ymax = SHORT2short( p2->blk.y_wid) - 1;
if ( ynow > ymax) return ( -2);
xw = SHORT2short( p2->blk.x_wid);
if ( SHORT2short( p2->header.depth) == 8) xw = (xw + 1) / 2;
if ( ynow == 0) {
cache8_pos = 0;
len2 = 0;
len = read_len();
if ( len == 1023) len2 = 1023;
else if ( len > 1023) {
len--;
}
cc = 0;
} else {
if ( SHORT2short( p2->header.depth) == 8) {
cc = vram_prev[ xw * 2 - 2];
cc = cc * 256 + vram_prev[ xw * 2 - 1];
} else {
cc = vram_prev[ xw - 1]; /* ひとつ前の色 */
}
}
memset( flag_next, 0, xw * sizeof( flag_next[0]));
for ( x = 0; x < xw; x++) {
char a = flag_now[ x];
if ( len2 > 0) {
if ( a < 0) { /* on chain ? */
cc = vram_now[x];
expand_chain( x, cc);
if ( --len2 == 0) {
len = read_len();
if ( len == 1023) len2 = 1023;
else if ( len > 1023) {
len--;
}
}
} else {
vram_now[x] = cc;
}
} else {
if ( a < 0) { /* on chain ? */
cc = vram_now[x];
expand_chain( x, cc);
} else if ( --len < 0) {
cc = vram_now[x] = read_color( cc);
expand_chain( x, cc);
len = read_len();
if ( len == 1023) len2 = 1023;
else if ( len > 1023) {
len--;
}
} else {
vram_now[x] = cc;
}
}
}
if ( line != NULL) {
if ( SHORT2short( p2->header.depth) == 8) {
long i;
for ( i = xw - 1; i >= 0; i--) {
ushort c = vram_now[i];
vram_now[ i * 2] = c / 256;
vram_now[ i * 2 + 1] = c & 255;
}
}
*line = vram_now;
}
ynow++;
para_in();
return ( ynow - 1);
}
/*
* 高速フォーマット展開の初期化
*/
long
p2sf_ld_init( P2 *p2)
{
long xw;
p2->ynow = 0;
switch ( SHORT2short( p2->header.depth)) {
case 24:
p2->func = read_color24;
break;
case 15:
p2->func = read_color15;
break;
case 8:
p2->func = read_color16;
break;
defalut:
p2errno= p2->errno = P2E_BADFORM;
return ( -1);
}
p2->nextline = line_expand;
seek_file( p2, p2->blk_pos + SIZE_OF_BLK);
xw = SHORT2short( p2->blk.x_wid);
memset( p2->cache, 0, sizeof( cache[0]) * 256);
memset( p2->cache_pos, 0, sizeof( cache_pos[0]) * 8 * 8 * 8);
memset( p2->flag_now, 0, (xw + 8) * sizeof( flag_now[0]));
memset( p2->flag_next, 0, (xw + 8) * sizeof( flag_next[0]));
p2->n_bit_buf = 0;
p2->n_fbuf = 0;
p2->bit_buf = 0;
return ( 0);
}
/* eof */